﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using ProjectRoughWork.Engine.SoundManager;
namespace ProjectRoughWork
{
    class SquadSelectionScreen : GameScreen
    {
        /// <summary>
        /// Default constructor. Initialies the data members of the class 
        /// </summary>

        public SquadSelectionScreen()
        {
            //Initialize list of components, sprite batch and sprite font

            components = new List<MenuComponent>();
            spriteBatch = Game1.GetSpriteBatch();
            spriteFont = Game1.GetSpriteFont();

            //Loads character image array with the images of the soldier, skirmisher and demolition man

            characterImgs = new Texture2D[3];
            characterImgs[0] = Game1.GetContentManager().Load<Texture2D>("SoldierImg");
            characterImgs[1] = Game1.GetContentManager().Load<Texture2D>("SkirmisherImg");
            characterImgs[2] = Game1.GetContentManager().Load<Texture2D>("DemolitionImg");

            //Initialize selection indexes to 0

            selectedComponent = 0;
            selectedCharacter = 0;

            //Initialize counts to 0

            soldierCount = 0;
            skirmisherCount = 0;
            demolitionCount = 0;

            //Initialize texts

            squadCompositionHeader = "Current Squad Composition";

            soldierText = "Soldiers: ";
            skirmisherText = "Skirmisher: ";
            demolitionText = "Demolition: ";
            enterPromptText = "Press Enter to Add a Unit or Launch the Game";
            backspacePromptText = "Press Backspace to Remove a Unit";

            // Play our player selection music
            SoundManager.GetInstance().playBackgroundMusic(SoundManager.BGM_MENU_SELECT_PLAYERS);

            InitMenuComponents();
        }

        /// <summary>
        /// Initializes the parameters of all the elements of the screen
        /// </summary>

        public void InitMenuComponents()
        {
            //Load background texture for selectable compoentns and retrieve width and height of screen

            Texture2D blue = Game1.GetContentManager().Load<Texture2D>("blueTexture");
            float screenWidth = Game1.GetGraphicsDevice().Viewport.Width;
            float screenHeight = Game1.GetGraphicsDevice().Viewport.Height;

            //Initialize Character Image Box parameters

            characterImgBox = new Rectangle(0, 0, 200, 200);
            imgBoxPos = new Vector2((int)2*screenWidth / 3, (int)screenHeight /4);
            imgBoxOrigin = new Vector2(characterImgBox.Width / 2, characterImgBox.Height / 2);

            //Initialize positions for the menu components

            Vector2 pos1 = new Vector2(screenWidth/5, screenHeight/10);
            Vector2 pos2 = new Vector2(pos1.X, pos1.Y + 30);
            Vector2 pos3 = new Vector2(pos1.X, pos2.Y + 30);

            Vector2 pos4 = new Vector2(pos1.X, pos3.Y + 40);

            //Initialize origin and position for squad composition header

            Vector2 tempOrigin = spriteFont.MeasureString(squadCompositionHeader);
            squadCompHeaderPos = new Vector2(pos1.X - tempOrigin.X/2, pos4.Y + 40);

            //Initialize orign and psoitions for the squad count texts

            tempOrigin = spriteFont.MeasureString(soldierText);
            soldierTextPos = new Vector2(pos1.X - tempOrigin.X/2, squadCompHeaderPos.Y + 40);
            
            tempOrigin = spriteFont.MeasureString(skirmisherText);
            skirmisherTextPos = new Vector2(pos1.X - tempOrigin.X/2, soldierTextPos.Y + 20);
            
            tempOrigin = spriteFont.MeasureString(demolitionText);
            demolitionTextPos = new Vector2(pos1.X - tempOrigin.X/2, skirmisherTextPos.Y + 20);

            tempOrigin = spriteFont.MeasureString(enterPromptText);
            enterPromptTextPos = new Vector2(0, screenHeight - tempOrigin.Y * 3);

            tempOrigin = spriteFont.MeasureString(backspacePromptText);
            backspacePromptTextPos = new Vector2(0, screenHeight - tempOrigin.Y * 2);

            //Initializes bounding boxes for selectable menu compoennts

            Rectangle bb1 = new Rectangle((int)pos1.X, (int)pos1.Y, 200, 25);
            Rectangle bb2 = new Rectangle((int)pos2.X, (int)pos2.Y, 200, 25);
            Rectangle bb3 = new Rectangle((int)pos3.X, (int)pos3.Y, 200, 25);

            Rectangle bb4 = new Rectangle((int)pos4.X, (int)pos4.Y, 100, 25);

            //Initialize selectable menu components

            MenuComponent comp1 = new MenuComponent(bb1,"Soldier",blue);
            MenuComponent comp2 = new MenuComponent(bb2, "Skirmisher", blue);
            MenuComponent comp3 = new MenuComponent(bb3, "Demolition", blue);

            MenuComponent comp4 = new MenuComponent(bb4, "Launch", blue);

            //Add Components to the list of components

            components.Add(comp1);
            components.Add(comp2);
            components.Add(comp3);
            components.Add(comp4);

            //Set the color of the text of the currently selected component to white

            components[selectedComponent].TextColor = Color.White;
        }

        /// <summary>
        /// Handles keyboard input for the squad selection screen
        /// </summary>
        /// <param name="inputKey">The keyboard state to be processed</param>

        public override void HandleInput(KeyboardState inputKey)
        {
            if ((inputKey.IsKeyDown(Keys.Down)) && (lastKeyInput.IsKeyUp(Keys.Down)))
            {
                if (selectedComponent != 3)
                {
                    //Update texts color to reflect the new selected component

                    components[selectedComponent].TextColor = Color.Red;
                    selectedComponent++;
                    components[selectedComponent].TextColor = Color.White;

                    //Update the image being drawn in the character image box if necessary

                    if (selectedComponent < 3)
                    {
                        selectedCharacter = selectedComponent;
                    }
                }
            }
            else if ((inputKey.IsKeyDown(Keys.Up)) && (lastKeyInput.IsKeyUp(Keys.Up)))
            {
                if (selectedComponent != 0)
                {
                    //Updates text colors to reflect currently selected components

                    components[selectedComponent].TextColor = Color.Red;
                    selectedComponent--;
                    components[selectedComponent].TextColor = Color.White;

                    //Updates selected character image to reflect the new selection

                    selectedCharacter = selectedComponent;
                }
            }
            else if ((inputKey.IsKeyDown(Keys.Enter)) && (lastKeyInput.IsKeyUp(Keys.Enter)))
            {
                if ((selectedComponent >= 0) && (selectedComponent <= 2) && 
                    ( (soldierCount + skirmisherCount + demolitionCount) < 3)
                    )
                {
                    //Incremeent the appropriate soldier count if the respective button is selected when pressing enter

                    switch (selectedComponent)
                    {
                        case 0:
                            soldierCount++;
                            break;
                        case 1:
                            skirmisherCount++;
                            break;
                        case 2:
                            demolitionCount++;
                            break;
                        default:
                            break;
                    }

                }
                else if (selectedComponent == 3)
                {
                    //If the toal count of the units matches the size of a squad, launch game

                    if (soldierCount + skirmisherCount + demolitionCount == 3)
                    {
                        LaunchGame();
                    }
                }
            }
            else if ((inputKey.IsKeyDown(Keys.Back)) && (lastKeyInput.IsKeyUp(Keys.Back)))
            {
                if ((selectedComponent >= 0) && (selectedComponent <= 2) &&
                    ((soldierCount + skirmisherCount + demolitionCount) > 0)
                    )
                {
                    //Decreases the unit count if the respective button is selected when Backspace is entered

                    switch (selectedComponent)
                    {
                        case 0:
                            if (soldierCount > 0)
                            {
                                soldierCount--;
                            }
                            break;
                        case 1:
                            if (skirmisherCount > 0)
                            {
                                skirmisherCount--;
                            }
                            break;
                        case 2:
                            if (demolitionCount > 0)
                            {
                                demolitionCount--;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }

            lastKeyInput = inputKey;
            base.HandleInput(inputKey);
        }

        public override void HandleInput(GamePadState inputButton)
        {
            if ((inputButton.IsButtonDown(Buttons.DPadDown)) && (lastButtonInput.IsButtonUp(Buttons.DPadDown)))
            {
                if (selectedComponent != 3)
                {
                    //Update texts color to reflect the new selected component

                    components[selectedComponent].TextColor = Color.Red;
                    selectedComponent++;
                    components[selectedComponent].TextColor = Color.White;

                    //Update the image being drawn in the character image box if necessary

                    if (selectedComponent < 3)
                    {
                        selectedCharacter = selectedComponent;
                    }
                }
            }
            else if ((inputButton.IsButtonDown(Buttons.DPadUp)) && (lastButtonInput.IsButtonUp(Buttons.DPadUp)))
            {
                if (selectedComponent != 0)
                {
                    //Updates text colors to reflect currently selected components

                    components[selectedComponent].TextColor = Color.Red;
                    selectedComponent--;
                    components[selectedComponent].TextColor = Color.White;

                    //Updates selected character image to reflect the new selection

                    selectedCharacter = selectedComponent;
                }
            }
            else if ((inputButton.IsButtonDown(Buttons.A)) && (lastButtonInput.IsButtonUp(Buttons.A)))
            {
                if ((selectedComponent >= 0) && (selectedComponent <= 2) &&
                    ((soldierCount + skirmisherCount + demolitionCount) < 3)
                    )
                {
                    //Incremeent the appropriate soldier count if the respective button is selected when pressing enter

                    switch (selectedComponent)
                    {
                        case 0:
                            soldierCount++;
                            break;
                        case 1:
                            skirmisherCount++;
                            break;
                        case 2:
                            demolitionCount++;
                            break;
                        default:
                            break;
                    }

                }
                else if (selectedComponent == 3)
                {
                    //If the toal count of the units matches the size of a squad, launch game

                    if (soldierCount + skirmisherCount + demolitionCount == 3)
                    {
                        LaunchGame();
                    }
                }
            }
            else if ((inputButton.IsButtonDown(Buttons.B)) && (lastButtonInput.IsButtonUp(Buttons.B)))
            {
                if ((selectedComponent >= 0) && (selectedComponent <= 2) &&
                    ((soldierCount + skirmisherCount + demolitionCount) > 0)
                    )
                {
                    //Decreases the unit count if the respective button is selected when Backspace is entered

                    switch (selectedComponent)
                    {
                        case 0:
                            soldierCount--;
                            break;
                        case 1:
                            skirmisherCount--;
                            break;
                        case 2:
                            demolitionCount--;
                            break;
                        default:
                            break;
                    }
                }
            }

            lastButtonInput = inputButton;            
        }

        /// <summary>
        /// Sets up the array of squad actors with the units selected and then triggers an event to the change the game state
        /// </summary>

        public void LaunchGame()
        {

            SquadActor[] squadActors = new SquadActor[3];

            int squadIndex = 0;
            SkinnedModel.firstRun = false;

            for (int index = 0; index < soldierCount; index++)
            {
                squadActors[squadIndex] = new Soldier("PlayerMarineBlue");
                squadIndex++;
            }

            for (int index = 0; index < skirmisherCount; index++)
            {
                squadActors[squadIndex] = new Skirmisher("PlayerMarineBlue");
                squadIndex++;
            }

            for (int index = 0; index < demolitionCount; index++)
            {
                squadActors[squadIndex] = new Demolition("PlayerMarineBlue");
                squadIndex++;
            }

            //Set the modelType for the player squad
 /*           for (int index = 0; index < squadIndex; index++)
            {
                squadActors[index].ModelType = "PlayerMarineBlue";
            }*/

            playerSquad = squadActors;
            


            EventChangeGameState stateEvt = new EventChangeGameState(ProjectGameLogic.GameState.Playing);
            EventManager.GetInstance().VTriggerEvent(stateEvt);
        }

        public SquadActor[] PlayerSquad
        {
            get { return playerSquad; }
        }

        /// <summary>
        /// Draws all the screen components
        /// </summary>

        public override void Draw()
        {
            //Draws all selectable components of the screen

            foreach (MenuComponent component in components)
            {
                component.Draw();
            }

            spriteBatch.Begin();

            //Draws the currently selected character

            spriteBatch.Draw(characterImgs[selectedCharacter], imgBoxPos, null, Color.White, 0f, imgBoxOrigin, 0.8f, SpriteEffects.None, 0f);
            
            //Draws the squad composition header and the current counts for each unit

            spriteBatch.DrawString(spriteFont, squadCompositionHeader, squadCompHeaderPos, Color.Red); 

            spriteBatch.DrawString(spriteFont, soldierText + soldierCount, soldierTextPos, Color.Red);
            spriteBatch.DrawString(spriteFont, skirmisherText + skirmisherCount, skirmisherTextPos, Color.Red);
            spriteBatch.DrawString(spriteFont, demolitionText + demolitionCount, demolitionTextPos, Color.Red);

            spriteBatch.DrawString(spriteFont, enterPromptText, enterPromptTextPos, Color.Red);
            spriteBatch.DrawString(spriteFont, backspacePromptText, backspacePromptTextPos, Color.Red);

            spriteBatch.End();

            base.Draw();
        }

        //Data Members

        SquadActor[] playerSquad;   //Array of the selected squad units

        int selectedComponent;      //Index of the current selected component
        int selectedCharacter;      //Index of the currently selected character

        int soldierCount;           //Number of soldiers currently selected
        int skirmisherCount;        //Number of skirmishers currently selected
        int demolitionCount;        //Number of demolition unit currently selected

        List<MenuComponent> components;         
        SpriteBatch spriteBatch;                
        SpriteFont spriteFont;
        Rectangle characterImgBox;
        Vector2 imgBoxPos;
        Vector2 imgBoxOrigin;
        Texture2D[] characterImgs;

        string squadCompositionHeader;
        string soldierText;
        string skirmisherText;
        string demolitionText;
        string enterPromptText;
        string backspacePromptText;
        Vector2 squadCompHeaderPos;
        Vector2 soldierTextPos;
        Vector2 skirmisherTextPos;
        Vector2 demolitionTextPos;
        Vector2 enterPromptTextPos;
        Vector2 backspacePromptTextPos;
    }
}
